import { _decorator, Button, Component, EventTouch, Label, Node, NodeEventType, Prefab, Size, Sprite, UITransform, Vec2, Vec3, view } from 'cc';
import { BasePanel } from '../Base/BasePanel';
import { Chess_Const } from './ChessConst';
import { Utilitys } from '../Utils/Utilitys';
import { ChessPane } from './ChessPane';
import { ChessDot } from './ChessDot';
import { ChessCommon } from './ChessCommon';
import { ChessMan } from './ChessMan';
import { SpriteUtil } from '../Utils/SpriteUtil';
import { TimeUtil } from '../Utils/TimeUtil';
import { PanelUtility } from '../Utility/PanelUtility';
import { Prefab_Type, RES_TYPE } from '../Data/GameConstant';
import { AlertUIPanel } from '../UI/AlertUIPanel';
import { SoundMgr } from '../Managers/SoundMgr';
import { ChessAI } from './ChessAI';
import { DisObjUtil } from '../Utils/DisObjUtil';
const { ccclass, property } = _decorator;

@ccclass('ChessUI')
export class ChessUIPanel extends BasePanel {

    public static Instance:ChessUIPanel = null;

    //#region child node
    @property(Node)
    public chessBg:Node = null;
    /**
     * 棋子着落点
     */
    @property(Node)
    public nodeDot:Node = null;
    /**
     * 棋子外框
     */
    @property(Node)
    public nodePane:Node = null;

    /**
     * 棋盘所有棋子节点
     */
    @property(Node)
    public nodeMan:Node = null;

    //
    @property(Node)
    public dotMC:Node = null;
    //
    @property(Node)
    public paneMC:Node = null;
    //spaceX,spaceY:(57,57)
    //帅（红方）的坐标：（0，-257） 大写
    //将（黑方）的坐标：（0，259）小写
    @property(Node)
    public manMC:Node = null;
    /**
     * 初级水平
     */
    @property(Button)
    public btnBaseLevel:Button;
    /**
     * 中级水平
     */
    @property(Button)
    public btnIntermediate:Button;
    /**
     * 大师水平
     */
    @property(Button)
    public btnMaster:Button;
    /**
     * 悔棋
     */
    @property(Button)
    public btnRegret:Button;
    /**
     * 棋谱
     */
    @property(Button)
    public btnGambit:Button;
    /**
     * msg
     */
    @property(Label)
    public lblMsg:Label;
    //
    public set SetLblMsg(msg:string){
        this.lblMsg.string = msg;
    }
    //#endregion

    onLoad(): void {
        if(null == ChessUIPanel.Instance){
            ChessUIPanel.Instance = this;
        }
    }

    start() {
        ChessCommon.Init();
        // SpriteUtil.Instance.preload();
        //
        this.chessBg.on(Node.EventType.TOUCH_START, this.OnTouchStartChessBg, this);
        this.chessBg.on(Node.EventType.TOUCH_END, this.OnTouchEndChessBg, this);
        this.bindBtnClick(this.btnBaseLevel, this.OnClickBaseLevelHandler);
        this.bindBtnClick(this.btnIntermediate, this.OnClickIntermediateLevelHandler);
        this.bindBtnClick(this.btnMaster, this.OnClickMasterLevelHandler);
        this.bindBtnClick(this.btnRegret, this.OnClickRegretHandler);
        this.bindBtnClick(this.btnGambit, this.OnClickGambitHandler);
    }
    //
    update(deltaTime: number) {}
    //
    private OnTouchStartChessBg(e:EventTouch):void{
        e.propagationStopped = true;
        this.OnChessTouchStartHandler(e);
        // this.TestTouchHandler(e);
    }
    //
    private OnTouchEndChessBg(e:EventTouch):void{
        e.propagationStopped = true;
    }
    //
    private OnChessTouchStartHandler(e:EventTouch):void{
        //
        if(!this.isPlay){
            return;
        }
        //屏幕坐标转换为棋盘坐标
        var colRow:Vec2 = ChessCommon.convertPosToChessRowCol(e.getUILocation(), this.chessBg.getPosition());
        if(!ChessCommon.IsValideRowCol(colRow.x, colRow.y)){
            console.error("[ChessUIPanel] row:" + colRow.y + ", col:" + colRow.x);
            return;
        }
        //
        var key:string = this.map[colRow.y][colRow.x];//获取点击的棋子
        console.log("[ChessUIPanel] key::" + key + ", row:" + colRow.y + ", col:" + colRow.x);
        if(ChessCommon.IsValideKey(key)){
            this.clickMan(key, colRow.x, colRow.y);
        }else{
            this.clickPoint(colRow.x, colRow.y);
        }
        this.isFoul = this.checkFoul();//检测是不是长将
    }
    
    //
    //#region 
    /**
     * 棋谱
     */
    private OnClickGambitHandler():void{
        this.YourWin();
    }
    /**
     * 悔棋
     */
    private OnClickRegretHandler():void{
        var map = ChessCommon.arr2Clone(ChessCommon.initMap);
        //初始化所有棋子
        for(var i=0; i < map.length; i++){
            for(var n=0; n < map[i].length; n++){
                var key = map[i][n];
                if(ChessCommon.IsValideKey(key)){
                    var man:ChessMan = this.mans[key];
                    man.SetKey(key).SetXY(n, i).SetShow(true);
                }
            }
        }
        //
        var pace = this.pace;
        pace.pop();
        pace.pop();
        //
        for(var i=0; i < pace.length; i++){
            var p = pace[i].split("");
            var x = parseInt(p[0], 10);
            var y = parseInt(p[1], 10);
            var newX = parseInt(p[2], 10);
            var newY = parseInt(p[3], 10);
            var key = map[y][x];

            var cMan = map[newY][newX];
            if(ChessCommon.IsValideKey(cMan)) this.mans[cMan].SetShow(false);
            this.mans[key].SetXY(newX, newY);
            map[newY][newX] = key;
            map[y][x] = "";
            //
            if(i == pace.length - 1){
                this.showPanes(x, y, newX, newY, this.mans[key].my);
            }
        }
        this.map = map;
        this.my = 1;
        this.isPlay = true;
    }
    /**
     * 初级水平
     */
    private OnClickBaseLevelHandler():void{
        this.InitChessGame(3);
    }
    /**
     * 中级水平
     */
    private OnClickIntermediateLevelHandler():void{
        this.InitChessGame(4);
    }
    /**
     * 大师水平
     */
    private OnClickMasterLevelHandler():void{
        this.InitChessGame(5);
    }
    //#endregion

    //#region 
    /**
     * 点击棋子，两种情况，选中或者吃子
     * @param key 
     * @param x 
     * @param y 
     */
    private clickMan(key:string, x:number, y:number):void{
        var man:ChessMan = this.mans[key];
        //吃子
        if(ChessCommon.IsValideKey(this.nowManKey) && this.nowManKey != key && man.my != this.mans[this.nowManKey].my){
            //man为被吃掉的棋子
            var nowMan:ChessMan = this.mans[this.nowManKey];
            if(this.indexOfPs(nowMan.ps, x, y)){
                man.SetShow(false);
                // 
                var paceStr = nowMan.x + "" + nowMan.y;
                //
                this.map[nowMan.y][nowMan.x] = "";
                this.map[y][x] = this.nowManKey;
                // 显示棋子外框
                this.showPanes(nowMan.x, nowMan.y, x, y, nowMan.my);
                //
                nowMan.SetXY(x, y);
                nowMan.alpha = 1;
                //
                this.pace.push(paceStr + x + y);
                this.nowManKey = "";
                this.hideDots();
                //
                SoundMgr.Instance.playEffect("chiChess_audio");
                TimeUtil.delayTime(()=>{
                    this.AIPlay();
                }, 1000);
                //
                this.checkWin(key);
            }
        }else{
            if(1 == man.my){
                if(this.mans[this.nowManKey]) this.mans[this.nowManKey].alpha = 1.0;
                man.alpha = 0.6;
                this.nowManKey = key;
                man.blps(this.map);//获取所有落子点
                this.showDots(man.ps);
                SoundMgr.Instance.playEffect("selectChess_audio");
            }
        }
    }
    /**
     * 点击着点
     * @param x 
     * @param y 
     */
    private clickPoint(x:number, y:number):void{
        var key:string = this.nowManKey;
        var man:ChessMan = this.mans[key];
        if(ChessCommon.IsValideKey(this.nowManKey)){
            if(this.indexOfPs(man.ps, x, y)){
                var paceStr = man.x + "" + man.y;
                this.map[man.y][man.x] = "";
                this.map[y][x] = key;
                this.showPanes(man.x, man.y, x, y, man.my);
                man.SetXY(x, y);
                man.alpha = 1;
                this.pace.push(paceStr + x + y);
                this.nowManKey = "";
                this.hideDots();
                //
                SoundMgr.Instance.playEffect("clickChess_audio");
                TimeUtil.delayTime(()=>{
                    this.AIPlay();
                }, 1000);
            }else{
                console.log("不能这样走！")
            }
        }
    }
    /**
     * 检查是否获胜
     * @param key 
     */
    private checkWin(key:string):void{
        if(key == "j0"){
            this.isPlay = false;
            this.YourLoser();
        }else if(key == "J0"){
            this.isPlay = false;
            this.YourLoser();
        }
    }
    /**
     * "您"赢啦
     */
    private YourWin():void{
        var alertUI = PanelUtility.Instance.showPopLayout(RES_TYPE.GUI, Prefab_Type.AlertUI, true);
        alertUI.getComponent(AlertUIPanel).SetData(1);
    }
    /**
     * "您"输啦
     */
    private YourLoser():void{
        var alertUI = PanelUtility.Instance.showPopLayout(RES_TYPE.GUI, Prefab_Type.AlertUI, true);
        alertUI.getComponent(AlertUIPanel).SetData(-1);
    }
    
    /**
     * 检查是否长将
     */
    public checkFoul1():string[]{
        var p:string[] = this.pace;
        var len:number = p.length;//parseInt(p.length, 10);
        if(len > 11 && p[len-1] == p[len-5] && p[len-5] == p[len-9]){
            var arr = p[len - 4].split("");
            return arr;
        }
        return null;
    }
    //检查是否长将
    public checkFoul():any{
        var p=this.pace;
        var len=parseInt(p.length, 10);
        if (len>11&&p[len-1] == p[len-5] &&p[len-5] == p[len-9]){
            return p[len-4].split("");
        }
        return false;
    }
    /**
     * Ai自动走棋
     */
    private AIPlay():void{
        this.my = -1;
        var ai_pace:number[] = ChessAI.init(this.pace.join(""));
        if(!ai_pace){
            this.YourWin();
            return;
        }
        //
        this.pace.push(ai_pace.join(""));
        var key = this.map[ai_pace[1]][ai_pace[0]];
        this.nowManKey = key;
        //
        key = this.map[ai_pace[3]][ai_pace[2]];
        if(ChessCommon.IsValideKey(key)){
            this.AIclickMan(key, ai_pace[2], ai_pace[3]);
        }else{
            this.AIclickPoint(ai_pace[2], ai_pace[3]);
        }
        SoundMgr.Instance.playEffect("clickChess_audio");
    }
    //
    private AIclickMan(key:string, x:number, y:number):void{
        var man:ChessMan = this.mans[key];
        //吃子
        man.SetShow(false);
        //
        var nowMan:ChessMan = this.mans[this.nowManKey];
        this.map[nowMan.y][nowMan.x] = "";
        this.map[y][x] = this.nowManKey;
        //
        this.showPanes(nowMan.x, nowMan.y, x, y, -1);
        nowMan.SetXY(x, y);
        this.nowManKey = "";
        //
        this.checkWin(key);
    }
    //
    private AIclickPoint(x:number, y:number):void{
        var key = this.nowManKey;
        var nowMan:ChessMan = this.mans[this.nowManKey];
        if(ChessCommon.IsValideKey(this.nowManKey)){
            this.map[nowMan.y][nowMan.x] = "";
            this.map[y][x] = key;
            //
            this.showPanes(nowMan.x, nowMan.y, x, y, -1);
            //
            nowMan.SetXY(x, y);
            this.nowManKey = "";
        }
    }
    /**
     * 判断 [x,y] 是否在落子点中
     * @param ps 
     * @param x 
     * @param y 
     */
    private indexOfPs(ps:number[][], x:number, y:number){
        for(var i=0; i < ps.length; i++){
            var arr:number[] = ps[i];
            if(arr[0] == x && arr[1] == y) return true;
        }
        return false;
    }
    //#endregion

    //#region 棋子着落点
    private _dots:ChessDot[];
    /**
     * 显示棋子着落点
     * @param ps 
     */
    private showDots(ps:number[][]):void{
        if(null == this._dots){
            this._dots = [];
        }
        //
        this.hideDots();
        var dotsLen = this._dots.length;
        for(var i=0; i < ps.length; i++){
            var mc:ChessDot;
            if(i < dotsLen){
                mc = this._dots[i];
            }else{
                mc = this.createChessDot();
                this._dots.push(mc);
            }
            //
            var arr:number[] = ps[i];
            var pos:Vec3 = ChessCommon.convertRowColToChessPos(arr[0], arr[1]);
            mc.SetPos(pos.x, pos.y).SetActive(true);
        }
    }
    
    /**
     * 隐藏棋子着落点
     */
    private hideDots():void{
        if(null != this._dots){
            for(var i=0; i < this._dots.length; i++){
                this._dots[i].SetActive(false);
            }
        }
    }

    /**
     * 创建棋子着落点
     * @returns 
     */
    private createChessDot():ChessDot{
        var mc = Utilitys.Instance.instantiate(this.dotMC);
        this.nodeDot.addChild(mc);
        return mc.addComponent(ChessDot);
    }
    //#endregion

    //#region 棋子外框
    private _panes:ChessPane[];
    /**
     * 显示移动的棋子外框
     */ 
    private showPanes(x:number, y:number, newX:number, newY:number, my:number):void{
        console.log("[ChessUIPanel] showPanes x:" + x + " ,y:" + y + " ,newX:" + newX + " ,newY:" + newY + " ,my:" + my);
        if(null == this._panes){
            this._panes = [];
            this._panes.push(this.createPane());
            this._panes.push(this.createPane());
        }
        //
        var mc0 = this._panes[0];
        mc0.SetPos(x, y).SetActive(true).SetMy(my);
        //
        var mc1 = this._panes[1];
        mc1.SetPos(newX, newY).SetActive(true).SetMy(my);
    }
    /**
     * 隐藏棋子外框
     */
    private hidePanes(){
        if(null != this._panes){
            for(var i=0; i < this._panes.length; i++){
                this._panes[i].SetActive(false);
            }
        }
    }
    /**
     * 创建 ChessPane
     * @returns 
     */
    private createPane():ChessPane{
        var mc:Node = Utilitys.Instance.instantiate(this.paneMC);
        this.nodePane.addChild(mc);
        return mc.addComponent(ChessPane);
    }
    //#endregion

    

    //#region 
    /**
     * 玩家方
     */
    public my:number = 1;
    
    /**
     * 现在要操作的棋子
     */
    public nowManKey:string;
    /**
     * 记录每一步
     */
    public pace:any;
    /**
     * 是否先手
     */
    public isOffensive:boolean = false;
    /**
     * 搜索深度
     */
    public depth:number = 3;
    /**
     * 是否犯规长将
     */
    public isFoul:any;
    /**
     * 是否能走棋
     */
    public isPlay:boolean = false;

    /**
     * 棋子布局
     */
    public map:string[][];
    /**
     * 棋子
     */
    public mans:{[key:string]:ChessMan} = {};

    /**
     * 初始化棋盘
     */
    private InitChessGame(depth:number):void{
        this.my = 1;
        this.map = ChessCommon.arr2Clone(ChessCommon.initMap);
        this.nowManKey = "";
        this.pace = [];
        this.isPlay = true;
        this.isOffensive = true;
        this.depth = depth;
        this.isFoul = null; //是否犯规长将
        
        this.hideDots();
        this.hidePanes();
        this.SetLblMsg = "";
        //初始化棋子
        for(var i=0; i < this.map.length; i++){
            for(var n=0; n < this.map[i].length; n++){
                var key:string = this.map[i][n];
                if(ChessCommon.IsValideKey(key)){
                    if(this.mans[key] != null){
                        this.mans[key].SetXY(n, i).SetShow(true);
                    }else{
                        var chessMan = this.CreateChessMan();
                        chessMan.SetKey(key).SetXY(n, i).SetShow(true);
                        //
                        this.mans[key] = chessMan;
                    }
                }
            }
        }
    }
    //
    private CreateChessMan():ChessMan{
        var mc = Utilitys.Instance.instantiate(this.manMC);
        this.nodeMan.addChild(mc);
        return mc.addComponent(ChessMan);
    }
    //#endregion
    //
    private TestTouchHandler(e:EventTouch):void{
        var colRow:Vec2 = ChessCommon.convertPosToChessRowCol(e.getUILocation(), this.chessBg.getPosition());
        var tpos = ChessCommon.convertRowColToChessPos(colRow.x, colRow.y);
        this.manMC.setPosition(tpos);
        this.manMC.active = true;
        console.log("[ChessUIPanel] colRow::" + colRow + ", tpos:" + tpos);
    }

    // //#region 坐标转换
    // /**
    //  * UI坐标 转换 棋盘坐标(行,列)
    //  * x:0~8 (共计9列， 从左到右依次递增) 
    //  * y:0~9 (共计10行， 从上到下依次递增)
    //  */
    // public convertPosToChessRowCol(pos:Vec2):Vec2{
    //     var x = Math.round((pos.x - Chess_Const.PointStartX) / Chess_Const.SpaceX);
    //     var y = Chess_Const.ROW - 1 - Math.round((pos.y - Chess_Const.PointStartY) / Chess_Const.SpaceY);
    //     return new Vec2(x, y);
    // }

    // //帅（红方）的坐标：（0，-257） 大写 (w:530, h:567)
    // //将（黑方）的坐标：（0，259）小写
    // /**
    //  * 换棋盘坐标(行,列) 转行 为棋盘UI坐标
    //  * x:0~8 (共计9列， 从左到右依次递增) 
    //  * y:0~9 (共计10行， 从上到下依次递增)
    //  */
    // public convertRowColToChessPos(pos:Vec2):Vec3{
    //     var x = Math.round(pos.x * Chess_Const.SpaceX  - (Chess_Const.COL - 1) * Chess_Const.SpaceX * 0.5);
    //     var y = Math.round((0 - pos.y) * Chess_Const.SpaceY + 259);
    //     return new Vec3(x, y, 0);
    // }
    // //#endregion
}

